package eu.tsp.isensors.impl.alert.gen;

import eu.tsp.isensors.services.alert.gen.ReceivedData;
import eu.tsp.isensors.services.alert.gen.TranslatedData;
import eu.tsp.isensors.services.translateData.TranslateData;

import java.util.List;
import java.util.ArrayList;


import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import java.net.URI;
import java.net.URISyntaxException;

import javax.xml.bind.JAXBException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.Marshaller;
import java.io.InputStream;
import java.io.ByteArrayInputStream;

import eu.tsp.isensors.impl.alert.schema.*;

import org.apache.felix.ipojo.annotations.Requires;
import org.apache.felix.ipojo.annotations.Property;
import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Provides;

@Component
@Provides
public class AlertGenerator implements ReceivedData,TranslatedData{
	
	@Property(mandatory=true)
	String recScriptID;
	
	@Property(mandatory=true)
	String trScriptID;
	
	@Property(mandatory=true)
	String configID;
	
	@Requires
	public eu.tsp.isensors.services.index.RunXQuery m_runquey;// Service Dependency
	
	@Requires
	public eu.tsp.isensors.services.translateData.TranslateData m_translateData;
	
	public eu.tsp.isensors.services.alert.trigger.AlertService m_alertService;
		
	String memory_rec="", memory_tr="";
	
	public void start() {
        	System.out.println(" >> start AlertGenerator");
    	}

    	public void stop() {
        	System.out.println(" >> stop AlertGenerator");
    	}

	public String thisIsReID(String nodeID, String uri, String data_id){
		System.out.println("vars v3 "+nodeID+" "+memory_rec+" "+data_id+" "+recScriptID+" "+configID+" ");
		byte[] b = m_runquey.execScript(nodeID, memory_rec, data_id, recScriptID.replaceAll("NODEID", nodeID), configID.replaceAll("NODEID", nodeID));
		String trID;
		if(b==null || b.length ==0 || (new String(b)).contains("<h2>HTTP ERROR: 404</h2>") || (new String(b)).contains("<exception>")) // Transformation pas faites ou script inexistant
		{	
			//There is no alert
			System.out.println("> thisIsReID : There is no alert");
			
		}else{
			processAlerts(b, memory_rec);
		}
		trID = m_translateData.translate(nodeID, uri, data_id);
		thisIsTrID(nodeID, uri, trID);
		return trID;
	}
	
	public String thisIsTrID(String nodeID, String uri, String data_id){
		byte[] b = m_runquey.execScript(nodeID, memory_tr, data_id, trScriptID.replaceAll("NODEID", nodeID), configID.replaceAll("NODEID", nodeID));
		if(b==null || b.length ==0 || (new String(b)).contains("<h2>HTTP ERROR: 404</h2>") || (new String(b)).contains("<exception>")) // Transformation pas faites ou script inexistant
		{	
			//There is no alert
			System.out.println("> thisIsTrID : There is no alert");
		
		}else{
			processAlerts(b, memory_tr);
        		
		}
		return data_id;
	}
	
	public boolean processAlerts(byte[] b, String saveMemory){
		ByteArrayInputStream input = new ByteArrayInputStream (b);
		System.out.println("> processAlerts : "+new String(b)+"***************");
		try {
			JAXBContext jc = JAXBContext.newInstance(eu.tsp.isensors.services.alert.schema.ObjectFactory.class);
			Unmarshaller unmarshaller = jc.createUnmarshaller();
		
			eu.tsp.isensors.services.alert.schema.GeneratedAlerts alerts = (eu.tsp.isensors.services.alert.schema.GeneratedAlerts)unmarshaller.unmarshal(input);
			saveMemory = alerts.getMemory();
			System.out.println("memory ::" + saveMemory +"::");
				
			// Déboguage
			//Marshaller m = jc.createMarshaller();
       			//m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        		//m.marshal( alerts, System.out );
        			
        		//Voir s'il y a bien des alertes
        		if(alerts.getAlerts().getAlert().size() != 0){
        			// @todo Envoyer les alertes à "Events Manager"
        			
        			/* Traitement que des alertes de type JMS
        			 *    Au lieu d'envoyer à l'alerte manager nous allons traiter ici les alertes de type JMS
        			 */
        				
        			m_alertService.newAlerts(alerts);
        			
        			
        		}
        			
        		return true;
        			
                } catch(JAXBException e){
                	e.printStackTrace();
        	}catch(Exception e){
			e.printStackTrace();
		}
		
		return false;
	}
	
	/*
	private String execScript(String nodeID, String data_id, String address, String uri_api, String memory, String scheme, String host, int port, String path){
		System.out.println("	execScript");
		HttpClient httpclient = new DefaultHttpClient();
                data_id = data_id.replaceAll("_", "/");
		try{
			System.out.println("	try{");
			List<NameValuePair> qparams = new ArrayList<NameValuePair>();
			qparams.add(new BasicNameValuePair("nodeID", nodeID));
			qparams.add(new BasicNameValuePair("data_id", data_id));
			qparams.add(new BasicNameValuePair("memory", memory));
			qparams.add(new BasicNameValuePair("uri_api", uri_api
				));
			URI uri = URIUtils.createURI(scheme, host, port, path, URLEncodedUtils.format(qparams, "UTF-8"), null);
                	HttpGet httpget = new HttpGet(uri);
                        
			HttpEntity entity = httpclient.execute(httpget).getEntity();
			
			if (entity != null) {
				System.out.println("	entity != null");
				//Thread.currentThread().getContextClassLoader();//.setContextClassLoader(this.getClass().getClassLoader());
				//ClassLoader cl = eu.tsp.isensors.impl.alert.schema.ObjectFactory.class.getClassLoader();
				//ClassLoader cl = Thread.currentThread().getContextClassLoader();
				JAXBContext jc = JAXBContext.newInstance(eu.tsp.isensors.impl.alert.schema.ObjectFactory.class);
				//JAXBContext jc = JAXBContext.newInstance("eu.tsp.isensors.impl.alert.schema");
				//JAXBContext jc = JAXBContext.newInstance("eu.tsp.isensors.impl.alert.schema", cl);
                        	Unmarshaller unmarshaller = jc.createUnmarshaller();
     				InputStream instream = entity.getContent();
     				
     				try {
     					//System.out.println("instream ::" + new String(IOUtils.toByteArray(instream))+"::");
         				//BufferedReader reader = new BufferedReader(
					//				new InputStreamReader(instream));
         				// do something useful with the response
         				//System.out.println(reader.readLine());
					GeneratedAlerts alerts = (GeneratedAlerts)unmarshaller.unmarshal(instream);
					memory = alerts.getMemory();
					System.out.println("memory ::" + memory +"::");
					
					Marshaller m = jc.createMarshaller();
       					m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        				m.marshal( alerts, System.out );

					
					
				//}catch (IOException e) {

     				} catch (RuntimeException ex) {

         				// In case of an unexpected exception you may want to abort
         				// the HTTP request in order to shut down the underlying
         				// connection and release it back to the connection manager.
         				httpget.abort();
         				//throw ex;
					ex.printStackTrace();

     				} finally {

         				// Closing the input stream will trigger connection release
         				instream.close();

     				}

     				// When HttpClient instance is no longer needed,
     				// shut down the connection manager to ensure
     				// immediate deallocation of all system resources
     				httpclient.getConnectionManager().shutdown();
 			}
                        //byte[] b = EntityUtils.toByteArray(httpclient.execute(httpget).getEntity());
                        //System.out.println(new String(b));
                        return "";
		} catch (NumberFormatException e) {
			e.printStackTrace();
		} catch (URISyntaxException e) {
			e.printStackTrace();
		} catch (javax.xml.bind.JAXBException e){
			 e.printStackTrace();
			
                } catch (ClientProtocolException ex) {
                        ex.printStackTrace();
                } catch (IOException ex) {
                        ex.printStackTrace();
                }
                return null;
	}
	
	*/
}
